package com.itheima.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.dubbo.config.annotation.Service;
import com.itheima.constant.MessageConstant;
import com.itheima.dao.MemberMapper;
import com.itheima.dao.OrderMapper;
import com.itheima.dao.OrderSettingMapper;
import com.itheima.entity.Result;
import com.itheima.pojo.Member;
import com.itheima.pojo.Order;
import com.itheima.pojo.OrderInfo;
import com.itheima.pojo.OrderSetting;
import com.itheima.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @description:
 * @author: dalao
 * @date: 2020/4/11-18:44
 * @Version: 1.0.0
 */
@Service(interfaceClass = OrderService.class)
@Transactional
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderSettingMapper orderSettingMapper;
    @Autowired
    private MemberMapper memberMapper;

    @Override
    public Result order(OrderInfo orderInfo) {
//        获取表单属性
        String telephone = orderInfo.getTelephone();
        Date orderDate = orderInfo.getOrderDate();
        String idCard = orderInfo.getIdCard();
        String name = orderInfo.getName();
        String sex = orderInfo.getSex();
        Integer setmealId = orderInfo.getSetmealId();
        String orderType = orderInfo.getOrderType();
        if (orderInfo != null) {
//          根据日期判断预约日期能否预约
            OrderSetting orderSetting = orderSettingMapper.findByDate(orderDate);
            if(orderSetting==null){
                return Result.ERROR(MessageConstant.SELECTED_DATE_CANNOT_ORDER);
            }
//            判断档期是否约满
            if(orderSetting.getNumber()<=orderSetting.getReservations()){
                return Result.ERROR(MessageConstant.ORDER_FULL);
            }
//            如果日期可以预约,根据手机号查询是否是会员
            Member member = memberMapper.findByTelephone(telephone);
//            如果不是会员,自动注册为会员,返回一个自动生成的id
            if(member==null){
                member= new Member();
                member.setName(name);
                member.setPhoneNumber(telephone);
                member.setIdCard(idCard);
                member.setRegTime(new Date());
                member.setSex(sex);
                memberMapper.add(member);
            }
//            获取用户的id
            Integer memberId = member.getId();
//            根据用户id,套餐id,预约日期查询是否已经预约
            Order order = new Order();
            order.setMemberId(memberId);
            order.setOrderDate(orderDate);
            order.setSetmealId(setmealId);
            List<Order> orderList = orderMapper.findByCondition(order);
//            如果存在不能预约
            if(CollectionUtil.isNotEmpty(orderList)){
                return Result.ERROR(MessageConstant.HAS_ORDERED);
            }
//            添加预约信息
            order.setOrderType(orderType);
            order.setOrderStatus(Order.ORDERSTATUS_NO);
            orderMapper.add(order);
//            更新预约列表 , 加入乐观锁 , 多个线程同时进入这个方法,但version在之前已经赋值了
//            如果第一个已经操作了version , 剩下的就不能对version操作 , 通过影响行数来判定
            int count = orderSettingMapper.updateReservations(orderSetting.getId(),orderSetting.getVersion());
//            抛出一个异常 controller捕获 , 提示用户信息
            if(count ==0){
                throw  new OptimisticLockingFailureException("网略异常");
            }
            return Result.OK(MessageConstant.ORDER_SUCCESS,order);
        }
        return Result.ERROR("请选择日期");
    }

    @Override
    public Map findById(Integer id) {
//      根据id查询预约信息
        Map map = orderMapper.findById4Detail(id);
        return map;
    }

    @Override
    public void updateOutTradeNo(Integer orderId, String outTradeNo) {
        orderMapper.updateOutTradeNo(orderId,outTradeNo);
    }

    @Override
    public void updatePayStatus(String out_trade_no) {
        orderMapper.updatePayStatus(out_trade_no);
    }
}
